package com.clg.protobuf.controller;

import com.clg.protobuf.dto.RequestDTO;
import com.clg.protobuf.dto.ResponseDTO;
import com.clg.protobuf.util.ClassUtil;
import com.clg.protobuf.util.ConstantUtil;
import com.clg.protobuf.util.HttpClientUtil;
import com.clg.protobuf.util.ProtoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

/**
 * Created by chenlong on 2017/6/1.
 */
@Controller
public class ProtobufController {

	private final Logger logger = LoggerFactory.getLogger(ProtobufController.class);

	@Autowired
	private HttpClientUtil httpClientUtil;

	@Autowired
	private ClassUtil classUtil;

	@Autowired
	private ProtoUtil protoUtil;

	/**
	 * 加载首页
	 * @return
	 */
	@GetMapping(value = {"/", "home", "index"})
	public String index(Model model) {
		model.addAttribute("protoFileList", ConstantUtil.protoFile);
		return "index";
	}

	/**
	 * 上传 proto 文件
	 * @param protoFile
	 * @return
	 */
	@ResponseBody
	@PostMapping("/uploadProtoFile")
	public String uploadProtoFile(@RequestParam("protoFile") MultipartFile protoFile) {
		if (!protoFile.isEmpty()) {
			try {
				// 文件名称
				String protoFileName = protoFile.getOriginalFilename();
				// 将上传的文件名保存到 protoFile list中供前端页面选择
				ConstantUtil.protoFile.add(protoFileName);
				// 创建文件
				File file = new File(ConstantUtil.PROTOBUF_FILE_PATH, protoFileName);
				protoFile.transferTo(file);

				// 将.proto文件生成java文件
				String className = protoUtil.generationJavaFile(protoFileName);
				// 动态编译java文件
                Class clazz = classUtil.dynamicLoad(className);
                String requestClassName = clazz.getName();
                logger.info("requestClassName：" + requestClassName);
			} catch (IOException e) {
				logger.error("proto文件上传失败！");
				e.printStackTrace();
				return "上传失败";
			} catch (ClassNotFoundException e) {
				logger.error("编译文件失败！");
				e.printStackTrace();
				return "编译失败";
			}
			return "上传成功";
		} else {
			return "上传失败";
		}
	}

	/**
	 * 执行请求
	 * @param requestDTO
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/executeHttpRequest")
	public ResponseDTO protobufRequest(RequestDTO requestDTO)
            throws ClassNotFoundException, NoSuchMethodException, IOException, IllegalAccessException, InvocationTargetException {
        Class dtoClass = null;
        // 请求数据类型为：application/x-protobuf
        if (ConstantUtil.MEDIA_TYPE_PROTOCOL_BUFFER.equalsIgnoreCase(requestDTO.getProtocolType())) {
            String protoFileName = requestDTO.getProtoFileName().replace(".proto", "");
            String dtoClassName = protoFileName.replace("Request", "");
            String requestClassName = ConstantUtil.PROTOBUF_PACKAGE_NAME + "." + protoFileName;
            // 加载内部类
            dtoClass = Class.forName(requestClassName + "$" + dtoClassName);
        }
		// 执行请求
        ResponseDTO responseDTO = httpClientUtil.executeHttpRequest(requestDTO, dtoClass);
		return responseDTO;
	}
}
